using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;

namespace Common.Unity.Configuration
{
	[TypeConverter( typeof(InjectionParameterValueTypeConverter) )]
	public abstract class InjectionParameterValue
	{
		public abstract Microsoft.Practices.Unity.InjectionParameterValue Create( Type targetType );
	}
	
	public abstract class GenericParameterBase : InjectionParameterValue
	{
		public string GenericParameterName { get; set; }
	}

	public class ResolvedArrayParameter : InjectionParameterValue
	{
		public Type ElementType { get; set; }

		public InjectionParameterValueCollection Values
		{
			get { return values ?? ( values = new InjectionParameterValueCollection() ); }
		}	InjectionParameterValueCollection values;

		public override Microsoft.Practices.Unity.InjectionParameterValue Create( Type targetType )
		{
			var result = new Microsoft.Practices.Unity.ResolvedArrayParameter( ElementType, Values.Resolve( targetType ) );
			return result;
		}
	}

	public class GenericParameter : GenericParameterBase
	{
		public string ResolutionKeyName { get; set; }

		public override Microsoft.Practices.Unity.InjectionParameterValue Create( Type targetType )
		{
			var result = new Microsoft.Practices.Unity.GenericParameter( GenericParameterName, ResolutionKeyName );
			return result;
		}
	}

	public class GenericResolvedArrayParameter : GenericParameterBase
	{
		public InjectionParameterValueCollection Values
		{
			get { return values ?? ( values = new InjectionParameterValueCollection() ); }
		}	InjectionParameterValueCollection values;

		public override Microsoft.Practices.Unity.InjectionParameterValue Create( Type targetType )
		{
			var result = new Microsoft.Practices.Unity.GenericResolvedArrayParameter( GenericParameterName, Values.Resolve( targetType ) );
			return result;
		}
	}
}